<template>
  <div class="operate-log-container">
    <!-- 页面标题 -->
    <h1 class="page-title">系统操作日志管理</h1>

<!-- 操作按钮区：添加排序切换按钮 -->
    <div class="button-container">
      <el-button 
        @click="handleToggleSort"
        type="primary"
        :icon="isDescending ? ArrowUp : ArrowDown"
        size="small"
      >
        {{ isDescending ? '查看最早' : '查看最新' }}
      </el-button>
    </div>

    <!-- 加载状态指示器 -->
    <el-loading v-if="loading" target=".operate-log-container" text="数据加载中..." />

    <!-- 表格组件：展示操作日志数据 -->
    <el-table
      v-else
      :data="tableData"
      stripe
      border
      style="width: 100%"
      :header-cell-style="{ 'text-align': 'center' }"
      :cell-style="{ 'text-align': 'center' }"
    >
      <!-- 日志ID列：唯一标识 -->
      <el-table-column prop="operateLogId" label="日志ID" width="80" sortable />

      <!-- 用户ID列：关联用户表 -->
      <el-table-column prop="userId" label="用户ID" width="80" sortable />

      <!-- 操作时间列：格式化显示 -->
      <el-table-column label="操作时间" width="180" sortable>
        <template #default="scope">
          {{ formatDateTime(scope.row.operateTime) }}
        </template>
      </el-table-column>

      <!-- 模块列：显示操作所属模块，使用标签增强可读性 -->
      <el-table-column prop="module" label="操作模块" width="120">
        <template #default="scope">
          <el-tag type="info">{{ scope.row.module || '-' }}</el-tag>
        </template>
      </el-table-column>

      <!-- 操作类型列：将英文类型转换为中文显示 -->
      <el-table-column label="操作类型" width="120" sortable>
        <template #default="scope">
          <el-tag :type="getOperateTypeTagType(scope.row.operateType)">
            {{ formatOperateType(scope.row.operateType) }}
          </el-tag>
        </template>
      </el-table-column>

      <!-- 操作内容列：显示操作描述 -->
      <el-table-column prop="operateContent" label="操作内容" width="200" />

      <!-- 操作IP列：显示操作来源IP -->
      <el-table-column prop="operateIp" label="操作IP" width="120" />

      <!-- 状态列：将数字状态转换为中文标签 -->
      <el-table-column label="操作状态" width="100" sortable>
        <template #default="scope">
          <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
            {{ scope.row.status === 1 ? '成功' : '失败' }}
          </el-tag>
        </template>
      </el-table-column>

      <!-- 请求参数列：JSON格式数据，使用tooltip展示完整内容 -->
      <el-table-column label="请求参数" min-width="180">
        <template #default="scope">
          <el-tooltip :content="formatJson(scope.row.requestParams)" placement="top">
            <div class="json-content">{{ truncateJson(scope.row.requestParams) }}</div>
          </el-tooltip>
        </template>
      </el-table-column>

      <!-- 返回结果列：JSON格式数据，使用tooltip展示完整内容 -->
      <el-table-column label="返回结果" min-width="180">
        <template #default="scope">
          <el-tooltip :content="formatJson(scope.row.responseResult)" placement="top">
            <div class="json-content">{{ truncateJson(scope.row.responseResult) }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页控件 -->
    <div class="pagination-container">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, reactive } from 'vue';
import { ElMessage, ElTooltip } from 'element-plus';
// 从API入口文件导入统一的api对象
import api from '@/api';
// 导入排序图标组件
import { ArrowUp, ArrowDown } from '@element-plus/icons-vue';

// 响应式状态管理
const state = reactive({
  allLogs: [], // 存储所有操作日志数据
  loading: true // 控制加载状态
});

// 分页相关状态
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const tableData = ref([]);

// 排序状态：默认为false(正序)，true表示倒序
const isDescending = ref(false);

/**
 * 格式化日期时间
 * 将ISO格式字符串转换为本地化日期时间，保留秒级精度
 * @param {string} dateTimeStr - ISO格式的日期时间字符串
 * @returns {string} 格式化后的日期时间
 */
const formatDateTime = (dateTimeStr) => {
  if (!dateTimeStr) return '-';
  const date = new Date(dateTimeStr);
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  }).replace(/\//g, '-');
};

/**
 * 格式化操作类型
 * 将后端返回的英文操作类型转换为中文显示，提升可读性
 * @param {string} type - 操作类型英文标识(add/update/delete/query)
 * @returns {string} 中文操作类型
 */
const formatOperateType = (type) => {
  const typeMap = {
    'add': '新增',
    'update': '更新',
    'delete': '删除',
    'query': '查询',
    'import': '导入',
    'export': '导出'
  };
  return typeMap[type] || type || '-';
};

/**
 * 获取操作类型标签样式
 * 根据不同操作类型使用不同颜色标签，便于视觉区分
 * @param {string} type - 操作类型
 * @returns {string} Element Plus标签类型
 */
const getOperateTypeTagType = (type) => {
  const typeMap = {
    'add': 'success',
    'update': 'warning',
    'delete': 'danger',
    'query': 'info'
  };
  return typeMap[type] || 'default';
};

/**
 * 格式化JSON字符串
 * 将JSON字符串格式化并高亮显示，便于查看复杂参数
 * @param {string} jsonStr - JSON格式字符串
 * @returns {string} 格式化后的JSON字符串
 */
const formatJson = (jsonStr) => {
  if (!jsonStr) return '无数据';
  try {
    // 尝试解析JSON，失败则原样返回
    const obj = JSON.parse(jsonStr);
    return JSON.stringify(obj, null, 2);
  } catch (e) {
    return jsonStr;
  }
};

/**
 * 截断JSON字符串
 * 表格中显示过长的JSON会影响布局，截断后显示前50个字符
 * @param {string} jsonStr - JSON格式字符串
 * @returns {string} 截断后的字符串
 */
const truncateJson = (jsonStr) => {
  if (!jsonStr) return '-';
  // 移除JSON中的空格和换行符，使截断更准确
  const plainText = jsonStr.replace(/\s+/g, '');
  return plainText.length > 50 ? plainText.slice(0, 50) + '...' : plainText;
};

/**
 * 处理分页大小变化
 * @param {number} val - 新的每页条数
 */
const handleSizeChange = (val) => {
  pageSize.value = val;
  currentPage.value = 1; // 切换页大小时重置到第一页
  setCurrentPageData();
};

/**
 * 切换排序方式
 * 点击按钮时切换正序/倒序状态，并重新排序数据
 */
const handleToggleSort = () => {
  isDescending.value = !isDescending.value; // 切换排序状态
  sortLogsByTime(); // 重新排序数据
  setCurrentPageData(); // 重新计算当前页数据
};

/**
 * 按时间排序日志数据
 * 根据操作时间(operateTime)字段排序，支持正序和倒序切换
 * 使用时间戳比较确保排序准确性，避免字符串比较导致的错误
 */
const sortLogsByTime = () => {
  state.allLogs.sort((a, b) => {
    const timeA = new Date(a.operateTime).getTime(); // 转换为时间戳
    const timeB = new Date(b.operateTime).getTime();
    return isDescending.value ? timeB - timeA : timeA - timeB; // 倒序/正序切换
  });
};

/**
 * 处理当前页码变化
 * @param {number} val - 新的页码
 */
const handleCurrentChange = (val) => {
  currentPage.value = val;
  setCurrentPageData();
};

/**
 * 设置当前页数据
 * 从所有数据中截取当前页所需数据，实现前端分页
 */
const setCurrentPageData = () => {
  const startIndex = (currentPage.value - 1) * pageSize.value;
  const endIndex = startIndex + pageSize.value;
  tableData.value = state.allLogs.slice(startIndex, endIndex);
};

/**
 * 获取所有操作日志
 * 调用后端全查接口，处理响应数据并初始化分页
 * 遵循与登录日志相同的错误处理和数据解析逻辑
 */
const fetchAllOperateLogs = async () => {
  try {
    state.loading = true;
    // 使用提取后的API方法，统一API调用方式
    const response = await api.sysOperateLogApi.getOperateLogList();
    
    // 验证接口返回格式：code为200且data为数组
    // 与登录日志保持一致的解析逻辑，避免格式判断错误
    if (response.code === 200 && Array.isArray(response.data)) {
      state.allLogs = response.data;
      sortLogsByTime(); // 数据加载后先按默认排序方式排序
      total.value = state.allLogs.length;
      setCurrentPageData();
    } else {
      ElMessage.error('获取操作日志失败：接口返回格式异常');
      state.allLogs = [];
      total.value = 0;
      tableData.value = [];
    }
  } catch (error) {
    console.error('操作日志请求失败:', error);
    ElMessage.error(`获取操作日志失败：${error.message || '网络异常'}`);
    state.allLogs = [];
    total.value = 0;
    tableData.value = [];
  } finally {
    state.loading = false;
  }
};

// 页面挂载时加载数据
onMounted(() => {
  fetchAllOperateLogs();
});
</script>

<style scoped>
/* 页面容器样式 */
.operate-log-container {
  padding: 20px;
  max-width: 1600px;
  margin: 0 auto;
}

/* 按钮容器样式：靠右对齐，与表格保持间距 */
.button-container {
  margin-bottom: 16px;
  text-align: right;
}

/* 页面标题样式 */
.page-title {
  color: #333;
  font-size: 20px;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

/* 分页容器样式 */
.pagination-container {
  margin-top: 20px;
  text-align: right;
}

/* JSON内容样式：设置最大高度和滚动条，避免tooltip内容过长 */
.json-content {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #606266;
}

/* 自定义tooltip样式：增加最大宽度和高度，支持滚动 */
:deep(.el-tooltip__popper) {
  max-width: 600px !important;
  max-height: 400px !important;
  overflow: auto;
}

/* tooltip内JSON格式化样式 */
:deep(.el-tooltip__popper pre) {
  font-family: monospace;
  white-space: pre-wrap;
  word-wrap: break-word;
  color: #333;
}
</style>